package com.chigga.admin.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.chigga.admin.domain.dto.*;
import com.chigga.admin.domain.entity.UserDO;
import com.chigga.admin.domain.vo.UserVO;
import com.chigga.admin.mapper.UserMapper;
import com.chigga.admin.service.UserService;
import com.chigga.common.core.domain.PageResult;
import com.chigga.common.exception.InstanceAlreadyExistsException;
import com.chigga.common.exception.InstanceNotExistsException;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;

import java.time.LocalDateTime;
import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;

/**
 * 用户服务实现类
 *
 * @author DefChigga
 */
@Slf4j
@Service
public class UserServiceImpl implements UserService {
    @Resource
    private UserMapper userMapper;

    @Resource
    private PasswordEncoder passwordEncoder;

    /**
     * 创建用户
     *
     * @param userCreateDTO 创建用户信息
     */
    @Override
    public Integer createUser(UserCreateDTO userCreateDTO) {
        // 校验创建用户名唯一性
        LambdaQueryWrapper<UserDO> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(UserDO::getUsername, userCreateDTO.getUsername());
        UserDO user = userMapper.selectOne(queryWrapper);
        if (user != null) {
            throw new InstanceAlreadyExistsException("创建用户名已存在");
        }
        // 转为DO
        UserDO userDO = new UserDO();
        BeanUtils.copyProperties(userCreateDTO, userDO);
        return userMapper.insert(userDO);
    }

    /**
     * 更新用户
     *
     * @param userUpdateDTO 更新用户信息
     */
    @Override
    public Integer updateUser(UserUpdateDTO userUpdateDTO) {
        // 校验更新用户是否存在
        UserDO userById = userMapper.selectById(userUpdateDTO.getId());
        if (userById == null) {
            throw new InstanceNotExistsException("更新用户不存在");
        }
        // 更新用户
        UserDO userDO = new UserDO();
        // 查询并设置版本号
        userDO.setVersion(userById.getVersion());
        BeanUtils.copyProperties(userUpdateDTO, userDO);
        return userMapper.updateById(userDO);
    }

    /**
     * 根据ID删除用户
     *
     * @param id 用户ID
     */
    @Override
    public Integer deleteUserById(Long id) {
        // 校验用户是否存在
        UserDO user = userMapper.selectById(id);
        if (user == null) {
            throw new InstanceNotExistsException("删除用户不存在");
        }
        // 删除用户
        return userMapper.deleteById(id);
    }

    /**
     * 批量删除用户
     *
     * @param ids 用户ID集合
     */
    @Override
    public Integer deleteUserBatchIds(List<Long> ids) {
        return userMapper.deleteByIds(ids);
    }

    /**
     * 查询用户列表
     *
     * @param userQueryDTO 查询条件
     * @return 用户列表
     */
    @Override
    public List<UserVO> selectUserList(UserQueryDTO userQueryDTO) {
        // 构造查询条件
        LambdaQueryWrapper<UserDO> queryWrapper = getLambdaQueryWrapper(userQueryDTO.getName(), userQueryDTO.getEmail(), userQueryDTO.getStatus(), userQueryDTO.getCreateStartTime(), userQueryDTO.getCreateEndTime());
        // 列表查询
        List<UserDO> userList = userMapper.selectList(queryWrapper);
        // 转换为VO
        return userList.stream().map(user -> {
            UserVO userVO = new UserVO();
            BeanUtils.copyProperties(user, userVO);
            return userVO;
        }).collect(Collectors.toList());
    }

    /**
     * 分页查询用户列表
     *
     * @param userPageQueryDTO 分页查询条件
     */
    @Override
    public PageResult<UserVO> selectUserPage(UserPageQueryDTO userPageQueryDTO) {
        // 构造分页条件
        Page<UserDO> page = new Page<>(userPageQueryDTO.getPageNum(), userPageQueryDTO.getPageSize());
        // 设置分页排序条件
        page.setOrders(userPageQueryDTO.getOrders());
        // 构造查询条件
        LambdaQueryWrapper<UserDO> queryWrapper = getLambdaQueryWrapper(userPageQueryDTO.getName(), userPageQueryDTO.getEmail(), userPageQueryDTO.getStatus(), userPageQueryDTO.getCreateStartTime(), userPageQueryDTO.getCreateEndTime());
        // 分页查询
        IPage<UserDO> selectPage = userMapper.selectPage(page, queryWrapper);
        // DO records 转换为 VO records
        selectPage.convert(userDO -> {
            UserVO userVO = new UserVO();
            BeanUtils.copyProperties(userDO, userVO);
            return userVO;
        });
        // 封装分页结果
        PageResult<UserVO> pageResult = new PageResult<>();
        BeanUtils.copyProperties(selectPage, pageResult);
        return pageResult;
    }

    /**
     * 根据ID查询用户
     *
     * @param id 用户ID
     * @return UserVO
     */
    @Override
    public UserVO selectUserById(Long id) {
        UserDO user = userMapper.selectById(id);
        if (user == null) {
            throw new InstanceNotExistsException("查询用户不存在");
        }
        UserVO userVO = new UserVO();
        BeanUtils.copyProperties(user, userVO);
        return userVO;
    }

    /**
     * 根据用户名查询用户
     * @param username 用户名
     * @return UserDO
     */
    @Override
    public UserDO selectUserByUsername(String username) {
        if(username == null) {
            throw new IllegalArgumentException("用户名不能为空");
        }
        LambdaQueryWrapper<UserDO> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(UserDO::getUsername, username);
        return userMapper.selectOne(queryWrapper);
    }

    /**
     * 注册用户
     *
     * @param userRegisterUsernameDTO 注册用户信息
     */
    @Override
    public Integer registerUser(UserRegisterUsernameDTO userRegisterUsernameDTO) {
        if(userRegisterUsernameDTO == null) {
            throw new IllegalArgumentException("注册用户信息不能为空");
        }
        if(selectUserByUsername(userRegisterUsernameDTO.getUsername()) != null) {
            throw new InstanceAlreadyExistsException("注册用户已存在");
        }
        // 新增用户
        UserDO user = new UserDO();
        BeanUtils.copyProperties(userRegisterUsernameDTO, user);
        user.setPassword(passwordEncoder.encode(user.getPassword()));
        user.setName(userRegisterUsernameDTO.getUsername());
        return userMapper.insert(user);
    }

    /**
     * 构造查询条件
     */
    private LambdaQueryWrapper<UserDO> getLambdaQueryWrapper(String name, String email, Boolean status, LocalDateTime createStartTime, LocalDateTime createEndTime) {
        LambdaQueryWrapper<UserDO> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper
                // 姓名模糊匹配
                .like(StringUtils.isNotBlank(name), UserDO::getName, name)
                // 邮箱模糊匹配
                .like(StringUtils.isNotBlank(email), UserDO::getEmail, email)
                // 状态相等
                .eq(Optional.ofNullable(status).isPresent(), UserDO::getStatus, status)
                // 开始时间 与 结束时间范围内
                .ge(Optional.ofNullable(createStartTime).isPresent(), UserDO::getCreateTime, createStartTime)
                .le(Optional.ofNullable(createEndTime).isPresent(), UserDO::getCreateTime, createEndTime);
        return queryWrapper;
    }
}
